package com.lzy.controller;

import com.lzy.base.BaseInfoProperties;
import com.lzy.grace.result.GraceJSONResult;
import com.lzy.grace.result.ResponseStatusEnum;
import com.lzy.pojo.Users;
import com.lzy.pojo.bo.RegistLoginBo;
import com.lzy.pojo.vo.UsersVO;
import com.lzy.service.UsersService;
import com.lzy.utils.IPUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;


@RestController
@RequestMapping("passport")
@Slf4j
public class PassportController extends BaseInfoProperties {


    @Autowired
    UsersService usersService;

    @PostMapping("getSMSCode")
    public GraceJSONResult getSMSCode(@RequestParam String mobile, HttpServletRequest request){

        // 如果传入的手机号为空,则返回错误信息
        if(StringUtils.isBlank(mobile)){
            return GraceJSONResult.error();
        }

        // 根据用户的手机号来限制用户在60秒内只能获得一次验证码。
        String userIP = IPUtil.getRequestIp(request);

        // value随意填写即可，因为仅仅只是用来锁住ip的，60秒过后，又能发送了
        // 也就是说，这个key存在，则当前ip用户无法发送验证码，直到key消失
        redis.setnx60s(MOBILE_SMSCODE + "limit:" + mobile, mobile);

        // 随机生成的6位验证码
        String code = (int)((Math.random() * 9 + 1) * 100000) + "";
        log.info("发送的验证码是:" + code);
        // 将验证码存储在redis中,用户后续的注册/登录的验证
        redis.set(MOBILE_SMSCODE + ":" + mobile,code,30 * 60);

        return GraceJSONResult.ok();
    }


    @PostMapping("regist")
    public GraceJSONResult regist(@Valid @NotNull @RequestBody RegistLoginBo registLoginBo,
                                  HttpServletRequest request){

        // 获得手机号和短信验证码
        String mobile = registLoginBo.getMobile();
        String code = registLoginBo.getSmsCode();
        String nickname = registLoginBo.getNickname();

        // 1. 用redis中获取验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        // 1.1 判断验证码是否过期或者验证码错误
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        // 2. 根据mobile查询数据库,如果用户存在,则提示无法注册
        Users user = usersService.queryMobileExist(mobile);
        if(user == null){
            // 2.1 如果查询的数据库为空,则表示用户没有注册,则需要进行用户信息的入库
            user = usersService.createUsers(mobile,nickname);
        }else{
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_ALREADY_EXIST_ERROR);
        }
        // 3. 用户注册成功后,删除redis中的短信验证码
        redis.del(MOBILE_SMSCODE + ":" + mobile);
        // 4. 设置用户分布式会话，保存用户的token令牌，存储到redis中
        String utoken = TOKEN_USER_PREFIX + SYMBOL_DOT + UUID.randomUUID();
        // 本方式只能限制用户在一台设备进行登录
        // redis.set(REDIS_USER_TOKEN + ":" + user.getId(),utoken);  // 设置分布式会话
        // 本方式允许用户在多台多设备进行登录
        redis.set(REDIS_USER_TOKEN + ":" + utoken,user.getId());  // 设置分布式会话
        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(user,usersVO);
        usersVO.setUserToken(utoken);

        // 5. 返回用户数据给前端
        return GraceJSONResult.ok(usersVO);
    }

    @PostMapping("login")
    public GraceJSONResult login(@Valid @RequestBody RegistLoginBo registLoginBo,
                                 HttpServletRequest request){

        // 获得手机号和短信验证码
        String mobile = registLoginBo.getMobile();
        String code = registLoginBo.getSmsCode();

        // 1. 用redis中获取验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        // 1.1 判断验证码是否过期或者验证码错误
        if(StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)){
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }
        // 2. 根据mobile查询数据库,如果用户存在,则提示无法注册
        Users user = usersService.queryMobileExist(mobile);
        if(user == null){
            // 2.1 如果查询的数据库为空,则表示用户没有注册,则返回错误信息
            return GraceJSONResult.errorCustom(ResponseStatusEnum.USER_NOT_EXIST_ERROR);
        }
        // 3. 用户登录成功后,删除redis中的短信验证码
        redis.del(MOBILE_SMSCODE + ":" + mobile);

        // 4. 设置用户分布式会话，保存用户的token令牌，存储到redis中
        String utoken = TOKEN_USER_PREFIX + SYMBOL_DOT + UUID.randomUUID();
        // 本方式只能限制用户在一台设备进行登录
        // redis.set(REDIS_USER_TOKEN + ":" + user.getId(),utoken);  // 设置分布式会话
        // 本方式允许用户在多台多设备进行登录
         redis.set(REDIS_USER_TOKEN + ":" + utoken,user.getId());  // 设置分布式会话
        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(user,usersVO);
        usersVO.setUserToken(utoken);
        // 5. 返回用户数据给前端
        return GraceJSONResult.ok(usersVO);
    }


    @PostMapping("logout")
    public GraceJSONResult logout(@RequestParam String userId,
                                 HttpServletRequest request){

        String utoken = request.getHeader("headerUserToken");
        //清除用户的分布式会话
        redis.del(REDIS_USER_TOKEN + ":" + utoken);
        return GraceJSONResult.ok();
    }
}
